package com.btnc.bpm.beans;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.StringReader;

import javax.annotation.Resource;
import javax.jbi.messaging.DeliveryChannel;
import javax.jbi.messaging.ExchangeStatus;
import javax.jbi.messaging.MessageExchange;
import javax.jbi.messaging.MessagingException;
import javax.jbi.messaging.NormalizedMessage;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

import org.apache.servicemix.jbi.jaxp.SourceTransformer;
import org.apache.servicemix.jbi.listener.MessageExchangeListener;
import org.w3c.dom.Attr;
import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

public class PosDetailsEnricherBean implements MessageExchangeListener {

	@Resource
	private DeliveryChannel channel;

	public void onMessageExchange(MessageExchange exchange)
			throws MessagingException {
		if (exchange.getStatus() == ExchangeStatus.ACTIVE) {
			NormalizedMessage message = exchange.getMessage("in");
			Source content = message.getContent();
			Source content1 = null;
			// process content according to your logic
			// e.g. to access the message body as a String use
			try {
				String body = (new SourceTransformer()).toString(content);
				String newBody = addPOSDetails(body);
				StringReader reader = new StringReader(newBody);
				content1 = new StreamSource(reader);

				message.setContent(content1);
				exchange.setMessage(message, "out");
				channel.send(exchange);
			} catch (TransformerException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (ParserConfigurationException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (SAXException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	private String addPOSDetails(String noteXML)
			throws ParserConfigurationException, SAXException, IOException,
			TransformerException {

		DocumentBuilderFactory builderFactory = DocumentBuilderFactory
				.newInstance();
		DocumentBuilder builder = builderFactory.newDocumentBuilder();
		Document document = builder.parse(new InputSource(new StringReader(
				noteXML)));
		NodeList nodes = document.getElementsByTagName("movingnote");
		Element element = (Element) nodes.item(0);
		NodeList nl = element.getElementsByTagName("pos");

		// Create DOM
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		DocumentBuilder builder1 = factory.newDocumentBuilder();
		DOMImplementation impl = builder1.getDOMImplementation();
		Document ecrichedDocument = impl.createDocument(null, "movingnote",
				null);
		Element enrichedElement = ecrichedDocument.getDocumentElement();

		Attr noteIdAtt = ecrichedDocument.createAttribute("id");
		noteIdAtt.setValue(element.getAttribute("id"));

		Element dateElement = ecrichedDocument.createElement("date");
		dateElement.setTextContent(getTextValue(element, "date"));

		Element posListElement = ecrichedDocument.createElement("posList");

		Constant constant = new Constant();
		for (int i = 0; nl != null && i < nl.getLength(); i++) {
			Element pos = (Element) nl.item(i);

			Element posElement = ecrichedDocument.createElement("pos");
			Attr posIdAtt = ecrichedDocument.createAttribute("id");
			String posID = pos.getAttribute("id");
			posIdAtt.setValue(posID);

			posElement.setAttributeNode(posIdAtt);

			//// ************************ ADDITIONAL DATA *******************************//
			
			Element nameElement = ecrichedDocument.createElement("name");
			nameElement.setTextContent(constant.names.get(posID));
			posElement.appendChild(nameElement);

			Element latElement = ecrichedDocument.createElement("latitude");
			latElement.setTextContent(constant.lats.get(posID));
			posElement.appendChild(latElement);

			Element lngElement = ecrichedDocument.createElement("longitude");
			lngElement.setTextContent(constant.lngs.get(posID));
			posElement.appendChild(lngElement);

			Element envelopeListElement = ecrichedDocument
					.createElement("envelopes");
			// ************************ END ADD NEW DATA *******************************//
			Node envelopes = pos.getFirstChild();
			NodeList nl2 = envelopes.getChildNodes();
			for (int j = 0; nl2 != null && j < nl2.getLength(); j++) {
				Element envelope = (Element) nl2.item(j);

				Element envelopeElement = ecrichedDocument
						.createElement("envelopeid");
				envelopeElement.setTextContent(envelope.getTextContent());
				envelopeListElement.appendChild(envelopeElement);
			}

			posElement.appendChild(envelopeListElement);

			posListElement.appendChild(posElement);
		}

		enrichedElement.setAttributeNode(noteIdAtt);
		enrichedElement.appendChild(dateElement);
		enrichedElement.appendChild(posListElement);

		DOMSource domSource = new DOMSource(enrichedElement);
		ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
		StreamResult streamResult = new StreamResult(outputStream);
		TransformerFactory transformerFactory = TransformerFactory
				.newInstance();
		Transformer serializer = transformerFactory.newTransformer();
		serializer.transform(domSource, streamResult);

		return outputStream.toString();
	}

	private String getTextValue(Element ele, String tagName) {
		String textVal = null;
		NodeList nl = ele.getElementsByTagName(tagName);
		if (nl != null && nl.getLength() > 0) {
			Element el = (Element) nl.item(0);
			textVal = el.getFirstChild().getNodeValue();
		}

		return textVal;
	}
}
